<template>
  <div class="register">
    <el-form
        ref="registerRef"
        :model="registerForm"
        :rules="registerRules"
        class="register-form"
    >
      <h3 class="title">用户注册</h3>
      <el-form-item prop="username">
        <el-input
            v-model="registerForm.username"
            type="text"
            size="large"
            auto-complete="off"
            placeholder="请输入用户名"
            prefix-icon="User"
        >
        </el-input>
      </el-form-item>
      <el-form-item prop="password">
        <el-input
            v-model="registerForm.password"
            type="password"
            size="large"
            auto-complete="off"
            placeholder="请输入密码"
            prefix-icon="Lock"
            show-password
        >
        </el-input>
      </el-form-item>
      <el-form-item prop="confirmPassword">
        <el-input
            v-model="registerForm.confirmPassword"
            type="password"
            size="large"
            auto-complete="off"
            placeholder="请确认密码"
            prefix-icon="Lock"
            show-password
        >
        </el-input>
      </el-form-item>
      <el-form-item prop="email">
        <el-input
            v-model="registerForm.email"
            type="text"
            size="large"
            auto-complete="off"
            placeholder="请输入邮箱（可选）"
            prefix-icon="Message"
        >
        </el-input>
      </el-form-item>
      <el-form-item prop="phonenumber">
        <el-input
            v-model="registerForm.phonenumber"
            type="text"
            size="large"
            auto-complete="off"
            placeholder="请输入手机号（可选）"
            prefix-icon="Phone"
        >
        </el-input>
      </el-form-item>
      <el-form-item style="width:100%;">
        <el-button
            :loading="loading"
            size="large"
            type="primary"
            style="width:100%;"
            @click="handleRegister"
        >
          <span>{{ loading ? '注册中...' : '注 册' }}</span>
        </el-button>
      </el-form-item>
      <div class="login-link">
        <span>已有账号？</span>
        <el-link type="primary" :underline="false" @click="goToLogin">
          立即登录
        </el-link>
      </div>
    </el-form>
  </div>
</template>

<script setup lang="ts">
// 导入 Vue Composition API 相关函数
import {ref, reactive} from 'vue'
// 导入 Vue Router 相关函数
import {useRouter, useRoute} from 'vue-router'
// 导入用户状态管理仓库
import {useUserStore} from '@/stores/user'
// 导入 Element Plus 组件和消息提示
import {ElMessage, ElForm} from 'element-plus'
// 导入注册表单类型定义
import type {RegisterForm} from '@/types/user'
// 导入 Element Plus 表单规则类型
import type {FormRules} from 'element-plus'

const router = useRouter() // 获取路由实例
const route = useRoute() // 获取当前路由信息
const userStore = useUserStore() // 获取用户状态管理仓库实例

/**
 * 注册表单数据模型
 * 使用reactive创建响应式表单对象，包含用户注册所需的基本信息字段
 * 各字段初始值均为空字符串，等待用户输入
 */
const registerForm = reactive<RegisterForm>({
  username: '',
  password: '',
  confirmPassword: '',
  email: '',
  phonenumber: ''
})

/**
 * 注册表单引用实例
 * 用于获取ElForm组件实例，以便调用表单相关方法如验证、重置等
 */
const registerRef = ref<InstanceType<typeof ElForm>>()

/**
 * 加载状态标识
 * 控制页面或组件的加载状态显示，true时显示加载效果，false时隐藏
 */
const loading = ref(false)


// 验证密码一致性
/**
 * 验证确认密码字段
 * @param _rule 验证规则对象
 * @param value 当前输入的确认密码值
 * @param callback 验证回调函数，用于返回验证结果
 */
const validateConfirmPassword = (_rule: any, value: string, callback: any) => {
  // 验证确认密码是否为空
  if (value === '') {
    callback(new Error('请再次输入密码'))
    // 验证确认密码与原密码是否一致
  } else if (value !== registerForm.password) {
    callback(new Error('两次输入密码不一致!'))
    // 验证通过
  } else {
    callback()
  }
}


/**
 * 注册表单验证规则配置
 *
 * 定义了用户注册时各个表单字段的验证规则，包括必填、长度、格式等验证
 * 该规则对象遵循 FormRules 类型约束
 */
const registerRules = {
  username: [
    {required: true, trigger: 'blur', message: '请输入用户名'},
    {min: 3, max: 20, trigger: 'blur', message: '用户名长度在 3 到 20 个字符'}
  ],
  password: [
    {required: true, trigger: 'blur', message: '请输入密码'},
    {min: 6, max: 20, trigger: 'blur', message: '密码长度在 6 到 20 个字符'}
  ],
  confirmPassword: [
    {required: true, validator: validateConfirmPassword, trigger: 'blur'}
  ],
  email: [
    {type: 'email', trigger: 'blur', message: '请输入正确的邮箱地址'}
  ],
  phonenumber: [
    {pattern: /^1[3-9]\d{9}$/, trigger: 'blur', message: '请输入正确的手机号'}
  ]
}satisfies FormRules
// 使用 satisfies FormRules 可以在保留对象字面量类型推断的同时满足 Element Plus 的类型要求。

// 处理注册
/**
 * 处理用户注册功能
 * @description 执行用户注册流程，包括表单验证、提交注册请求、处理注册结果
 * @returns {Promise<void>} 无返回值
 */
const handleRegister = async () => {
  // 检查注册表单引用是否存在
  if (!registerRef.value) return

  // 验证表单数据
  await registerRef.value.validate(async (valid: boolean) => {
    // 如果表单验证失败则直接返回
    if (!valid) return

    // 设置加载状态为true，显示加载效果
    loading.value = true
    try {
      // 调用用户store的注册方法，提交注册信息
      const result = await userStore.register({
        username: registerForm.username, // 用户名
        password: registerForm.password, // 密码
        email: registerForm.email, // 邮箱
        phonenumber: registerForm.phonenumber // 手机号
      })
      console.log("result.success:", result)
      // 根据注册结果进行相应处理
      if (result.success) {
        // 注册成功，显示成功消息并跳转到登录页面
        ElMessage.success(result.message)
        
        // 检查是否有重定向参数，注册后携带到登录页面
        const redirect = route.query.redirect as string
        if (redirect) {
          router.push({ path: '/login', query: { redirect } })
        } else {
          router.push('/login')
        }
      } else {
        // 注册失败，显示错误消息
        ElMessage.error(result.message)
      }
    } catch (error) {
      // 捕获注册过程中的异常，显示错误提示
      ElMessage.error('注册失败，请稍后重试')
    } finally {
      // 无论注册成功与否，最终都要关闭加载状态
      loading.value = false
    }
  })
}


// 跳转到登录页
const goToLogin = () => {
  router.push('/login')
}
</script>

<style scoped lang="scss">
.register {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background-image: url("@/assets/images/bg.png");
  background-size: cover;

  .register-form {
    border-radius: 6px;
    background: #ffffff;
    width: 400px;
    padding: 25px 25px 25px 25px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);

    .title {
      margin: 0 auto 30px;
      text-align: center;
      color: #707070;
      font-size: 20px;
      font-weight: bold;
    }

    .el-input {
      height: 40px;

      :deep(.el-input__wrapper) {
        padding: 0 15px;
      }
    }

    .login-link {
      text-align: center;
      margin-top: 20px;
      font-size: 14px;
      color: #606266;
    }
  }
}
</style>
